package com.hzgj.bcl.soa.stats;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import com.hzgj.bcl.soa.util.Constants;
import com.hzgj.bcl.util.jmx.Management;
import com.hzgj.bcl.util.jmx.annotation.MBean;
import com.hzgj.bcl.util.jmx.annotation.ManagedOperation;

import java.util.Iterator;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;

/**
 * Created by Administrator on 2016/8/15.
 */
@MBean(description = "Stats Collectors")
public class StatsCollectors {

    public Set<Stats> enables = Sets.newConcurrentHashSet();
    public Map<String, Stats> all = Maps.newHashMap();

    public static final StatsCollectors getInstance() {
        return LazyHolder.instance;
    }

    public void load() {
        ServiceLoader<Stats> serviceLoader = ServiceLoader.load(Stats.class);
        Iterator<Stats> iterator = serviceLoader.iterator();
        while (iterator.hasNext()) {
            Stats stats = iterator.next();
            if (stats.enabled()) {
                stats.start();
                enables.add(stats);
                if (stats.getClass().getAnnotation(MBean.class) != null) {
                    Management.register(stats, Constants.OBJECTNAME_PREFIX + Constants.OBJECTNAME_STATS + ",name = " + stats.getName());
                }
            }
            all.put(stats.getName(), stats);
        }
    }

    public void invoke(StatsData statsData) {
        enables.forEach(stats -> stats.report(statsData));
    }

    @ManagedOperation(description = "enable stats by name")
    public boolean enable(String name) {
        Stats stats = all.get(name);
        if (stats != null) {
            stats.start();
            enables.add(stats);
        } else {
            return false;
        }
        return true;
    }

    @ManagedOperation(description = "disable stats by name")
    public boolean disable(String name) {
        Stats stats = all.get(name);
        if (stats != null) {
            stats.stop();
            enables.remove(stats);
        } else {
            return false;
        }
        return true;
    }

    private static class LazyHolder {
        private static final StatsCollectors instance = new StatsCollectors();
    }

}
